package com.fengye.common.exception;

import com.fengye.common.domain.ResponseResult;
import com.fengye.common.constants.AppHttpCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * @author sunlei
 * @version 1.0
 * @date 2023/9/11 20:03:01
 * @description 全局异常处理类
 */
@Slf4j
@RestControllerAdvice // 相当于@RestControllerAdvice = @ControllerAdvice + @ResponseBody
public class GlobalExceptioinHandler {

    /**
     * 参数验证异常处理
     */
    @ExceptionHandler(BindException.class)
    public ResponseResult<Object> paramValidation(BindException ex) {
        FieldError fieldError = ex.getBindingResult().getFieldError();
        commonPrintError(ex);
        return ResponseResult.fail(AppHttpCodeEnum.PARAM_ERROR).setMessage(!Objects.isNull(fieldError) ? fieldError.getDefaultMessage() : AppHttpCodeEnum.PARAM_ERROR.getMsg());
    }

    /**
     * 业务异常处理
     */
    @ExceptionHandler(BusinessException.class)
    public ResponseResult<Object> customExceptionHandler(BusinessException exception) {
        commonPrintError(exception);
        return ResponseResult.fail(exception.getErrorEnum());
    }

    /**
     * 通用异常处理方法
     */
    @ExceptionHandler
    public ResponseResult<Object> commonExceptionHandler(Exception exception) {
        commonPrintError(exception);
        String message = Objects.isNull(exception.getMessage()) ? AppHttpCodeEnum.SYSTEM_ERROR.getMsg():exception.getMessage();
        return ResponseResult.fail(AppHttpCodeEnum.SYSTEM_ERROR).setMessage(message);
    }

    /**
     * 错误统一输出格式
     *
     * @param e 错误对象
     */
    public void commonPrintError(Exception e) {
        e.printStackTrace();

        String errmsg = e.getMessage();
        StackTraceElement[] stackTraceElements = e.getStackTrace();
        if (stackTraceElements.length != 0){
            StackTraceElement stackTraceElement = stackTraceElements[0];
            errmsg += "\n" + "问题出处：" + stackTraceElement.toString();
        }
        log.error(errmsg);
    }
}
